home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Libraries / VideoToolbox 97.08.16 / (Demos) / TimeCPU.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-09  |  31.7 KB  |  1,223 lines  |  [TEXT/CWIE]

  1. /*
  2. TimeCPU.c
  3. Denis G. Pelli, 1991-1995
  4. This routine uses my Timer.c to measure the timing of basic CPU
  5. operations and several random number generators. (Apple's Microseconds() routine
  6. would do just as well, instead of Timer.c, but wasn't available when I wrote this.) 
  7. The timing seems to be very accurate. It ought to be as accurate as the
  8. frequency of the oscillator in the VIA chip. However, I haven't checked the
  9. timing against a known standard.
  10.  
  11. The Fixed data type is predefined by Apple as a long (i.e. 32 bits) with an assumed 
  12. decimal point in the middle.
  13.  
  14. The access to video memory overwrites a small part of your main screen, the
  15. first 40 bytes. This will be in the upper left hand corner of your display, and
  16. will usually be barely noticeable. I like seeing that, as it confirms that the
  17. program really is accessing the video memory.
  18.  
  19. This program requests a memory partition of 900K. It will run in less, but will
  20. then do fewer iterations.
  21.  
  22. NOTE: This file is part of the VideoToolbox archive of C sources for the Mac. 
  23. You can download the whole VideoToolbox from any Info-Mac mirror:
  24. ftp://mirror.apple.com/mirrors/info-mac/dev/lib/video-toolbox-95-11-10-c.hqx
  25. ftp://mirrors.aol.com/pub/info-mac/dev/lib/video-toolbox-95-11-10-c.hqx
  26.  
  27. The glue libraries NameRegistryLib and DriverServicesLib are in the VideoToolbox Libs folder. 
  28.  
  29. REFERENCE:
  30. TechNote 1083 Weak-linking to a Code Fragment Manager-based shared library
  31. http://devworld.apple.com/dev/technotes/tn/tn1083.html
  32.  
  33. HISTORY:
  34. 1/91    dgp    wrote it
  35. 2/16/91    dgp    added fpu test, to fail gracefully if compiled with FPU support, but FPU
  36.             is not present.
  37. 3/4/91    dgp    added timing of random number generators
  38. 8/6/91    dgp    added timing of RandFill.
  39. 8/24/91    dgp    Made compatible with THINK C 5.0.
  40. 1/25/92    dgp    Calibrate and correct for the slowness of TimeIt(). 
  41.             Measure and subtract off the small loop overhead.
  42.             Identify machine and compiler.
  43.             Automatically append results to TimeCPU.data file.
  44. 1/29/92    dgp    Time move from memory to video memory, for showing movies.
  45.             Added transcendental functions since Radius 8881 init and System 7.01
  46.             speed them up dramatically and the Quadra is reputed to
  47.             do them very slowly.
  48. 1/30/92    dgp    Access video memory only in 32-bit mode, to avoid crashes.
  49. 8/19/92    dgp    time the 68881 instructions _sin, _sqrt, _exp, _log
  50.             Use new Timer.c instead of old TimeIt.c
  51. 8/28/92    dgp    updated to use new reentrant Timer.c
  52. 11/18/92 dgp renamed output file to “TimeCPU results”
  53. 1/11/93    dgp    check for presence of 68020. Put Gestalt tests in main, without
  54.             any fpu usage, since program was crashing when fpu was absent
  55.             before getting to the fpu test. (Supposedly that was fixed
  56.             in THINK C 5. Oh well.)
  57. 2/7/93    dgp    added timing of SetPixelsQuickly().
  58. 7/9/93    dgp check for 32-bit addressing capability.
  59. 3/13/94    dgp    added timing of short arithmetic, and put conditionals around each section.
  60. 6/1/94    dgp    added timing of BlockMoveData().
  61. 6/14/94    dgp    can32 is now computed by calling TrapAvailable(_SwapMMUMode), which 
  62.             returns the correct answer even on Macs with dirty ROMs.
  63. 7/31/94    dgp made compatible with new SANE.h in Universal Headers.
  64. 9/5/94 dgp removed assumption in printf's that int==short.
  65. 10/2/94    dgp deleted RandomX() since it's part of SANE, which doesn't exist on PowerPC,
  66.             and, in any event, was uselessly slow on 68k machines. Tidied up the
  67.             printout for readability even for computers as fast as the PowerPC.
  68. 4/9/95 dgp added a few tests relevant to nrand(). Increased n. Polished the printout a bit.
  69. 4/11/95 dgp changed declaration of bufferHandle from void ** to Handle, for compatibility with
  70. old pre-universal apple headers.
  71. 5/23/95 dgp Apple changed the prototype in the header file from SwapMMUMode(char *) to 
  72.             SwapMMUMode(signed char *). To retain compatibility with both old and new
  73.             headers, I cast the argument (void *).
  74. 11/20/95 dgp added timing of moves using float pointers, since they're supposed to be fast on the PowerPCs.
  75. 1/28/96 dgp only call BlockMoveDataUncached on PCI Macs; otherwise use BlockMoveData.
  76. 3/4/96 dgp made compatible with THINK C 7.
  77. 4/10/97    dgp    Eliminate stuff that was conditional on !UNIVERSAL_HEADERS.
  78. 7/9/97    dgp    Simplified the test for availability of BlockCopy and BlockMoveDataUncached, based on TN1083.
  79.             Eliminated the confusing redefinition of BlockCopy and BlockMoveDataUncached, and instead
  80.             enclosed all instances in #ifs.
  81. */
  82. #include "VideoToolbox.h"
  83. #ifndef __TRAPS__
  84.     #include <Traps.h>    // _SwapMMUMode
  85. #endif
  86. //#include <Menus.h>    // DrawMenuBar
  87. void ShrinkRect(Rect *r,int hDivisor,int vDivisor);
  88. void ExpandRect(Rect *r,double hMag,double vMag);
  89. void ExpandAndOffsetRect(Rect *r,double hMag,double vMag,double hOffset,double vOffset);
  90.  
  91. void TimeCPU(void);
  92. #if GENERATINGPOWERPC
  93.     // BlockMoveDataUncached is only available on PowerPC. Apparently video buffers are "uncacheable" and
  94.     // BlockMoveData uses an instruction that is emulated slowly in that case.
  95.     extern void BlockCopy(const void *srcPtr, void *destPtr, Size byteCount);
  96.     extern void BlockMoveDataUncached(const void *srcPtr, void *destPtr, Size byteCount);
  97. #endif
  98. #ifndef __CODEFRAGMENTS__
  99.     #include <CodeFragments.h>
  100. #endif
  101.  
  102. void main(void)
  103. {
  104.     long value;
  105.  
  106.     Require(gestaltOriginalQD);
  107.     Gestalt(gestaltTimeMgrVersion,&value);
  108.     if(value<gestaltRevisedTimeMgr)
  109.         PrintfExit("Sorry, your System is too old; I need at least \n"
  110.             "the Revised Time Manager.\n");
  111.     TimeCPU();
  112. }
  113.  
  114. void TimeCPU(void)
  115. {
  116.     long n,quickDraw;
  117.     short i;
  118.     register long *paL,*pbL,iL,jL,kL,mL;
  119.     double x,y,z;
  120.     Fixed xF,yF,zF;
  121.     Handle bufferHandle;
  122.     void *buffer,*buffer2;
  123.     char Buffer[32];
  124.     FILE *o[2],*dataFile;
  125.     GDHandle device;
  126.     double s,s0,overhead;
  127.     Timer *timer;
  128.     OSErr osErr,error;
  129.     long value;
  130.     Boolean can32;
  131.     Boolean pci;    // Is this a PCI Mac? Only the PCI Macs have BlockMoveDataUncached.
  132.  
  133.     MaximizeConsoleHeight();
  134.     /* INITIALIZE QuickDraw */
  135.     #if (THINK_C || THINK_CPLUS || SYMANTEC_C)
  136.         console_options.ncols = 90;
  137.     #elif __MWERKS__
  138.         SIOUXSettings.columns=90;
  139.     #elif
  140.         InitGraf(&qd.thePort);
  141.         InitFonts();
  142.         InitWindows();
  143.         InitCursor();
  144.     #endif
  145.     printf("Welcome to TimeCPU.\n");
  146.     assert(StackSpace()>4000);
  147.     can32=TrapAvailable(_SwapMMUMode);
  148.     timer=NewTimer();
  149.     #define gestaltNameRegistryVersion 'nreg'    // support old versions of Gestalt.h
  150.     error=Gestalt(gestaltNameRegistryVersion,&value);
  151.     pci=(error==0);    // are there PCI slots?
  152.     #if GENERATINGCFM && GENERATINGPOWERPC
  153.         if(pci){
  154.             // The BlockMoveDataUncached glue is in a shared library.
  155.             // If the DriverServicesLib is weak-linked, and missing, we need to
  156.             // check for the library, to prevent a crash if we try to access the 
  157.             // library's exports.
  158.             /*
  159.             CFragConnectionID        connID;
  160.             Ptr                        mainAddr;
  161.             Str255                    errName;
  162.             long templong;
  163.             int error;
  164.             
  165.             error=Gestalt(gestaltCFMAttr,&templong);    // Code Fragment Manager?
  166.             if(!error){
  167.                 error=GetSharedLibrary((ConstStr63Param)"\pDriverServicesLib"
  168.                     ,kAnyCFragArch,kFindCFrag,&connID,&mainAddr,errName);
  169.                 if(error)PrintfExit("\nCouldn't load %#s. GetSharedLibrary error=%d\n\007",errName,(int)error);
  170.             }
  171.             */
  172.             error = (Ptr)BlockMoveDataUncached == (Ptr)kUnresolvedCFragSymbolAddress;
  173.             if(error)PrintfExit("\nDriverServicesLib missing.\n\007");
  174.         }
  175.     #endif
  176.     o[0]=stdout;
  177.     o[1]=dataFile=fopen("TimeCPU results","a");    /* Append to data file */
  178.     if(dataFile!=NULL){
  179.         printf("Key results will be appended to “TimeCPU results” file.\n\n");
  180.         SetFileInfo("TimeCPU results",'TEXT','ttxt');
  181.     }
  182.     else printf("Could not open “TimeCPU results” file\n\n");
  183.     ffprintf(o,"\n%s\n",BreakLines(IdentifyMachine(),80));
  184.     ffprintf(o,"%s\n\n",BreakLines(IdentifyCompiler(),80));
  185.     ffprintf(o,"      Time    Operation\n");
  186.     srand(clock());
  187.     y=sqrt(2.0);
  188.     z=sqrt(3.0);
  189.     kL=y*1000.;
  190.     mL=z*10.;
  191.     RandFill(Buffer,sizeof(Buffer));
  192.         
  193.     n=100000;    // REDUCE THIS NUMBER TO SPEED UP THE TESTING, BUT REDUCE PRECISION.
  194.     overhead=0.0;
  195.     StartTimer(timer);
  196.     for(iL=n/10;iL>0;iL--) ;
  197.     overhead=StopTimerSecs(timer)/n-overhead;    // the loop overhead per operation
  198.  
  199. // Time various ways of moving memory    
  200.     for(;n>0;){
  201.         bufferHandle=NewHandle(2*sizeof(long)*n);
  202.         if(bufferHandle==NULL)bufferHandle=TempNewHandle(2*sizeof(long)*n,&osErr);
  203.         if(bufferHandle!=NULL)break;
  204.         n/=2;
  205.         printf("Reducing iterations to %ld to fit in available memory.\n",n);
  206.     }
  207.     assert(bufferHandle!=NULL);
  208.     HLockHi(bufferHandle);
  209.     buffer=*bufferHandle;
  210.     buffer=(void *)(((unsigned long)buffer+15) & ~15UL);    // round up to multiple of 16
  211.     buffer2=(long *)buffer+n;
  212.     buffer2=(void *)((unsigned long)buffer2 & ~15UL);    // round down to multiple of 16
  213.     {
  214.         StartTimer(timer);
  215.         BlockMove(buffer2,buffer,4*n);
  216.         s=StopTimerSecs(timer);
  217.         ffprintf(o,"%11.3f ms    BlockMove(,,%ld);    // %.1f MB/s\n"
  218.             ,s*1e3,n*4,n*4/1024./1024./s);
  219.     }
  220.     {
  221.         StartTimer(timer);
  222.         BlockMoveData(buffer2,buffer,4*n);
  223.         s=StopTimerSecs(timer);
  224.         ffprintf(o,"%11.3f ms    BlockMoveData(,,%ld);    // %.1f MB/s\n"
  225.             ,s*1e3,n*4,n*4/1024./1024./s);
  226.     }
  227.     {
  228.         register double *paF,*pbF;
  229.  
  230.         n/=sizeof(*paF)/4;
  231.         paF=(void *)buffer;
  232.         pbF=(void *)buffer2;
  233.         StartTimer(timer);
  234.         for(iL=n/10;iL>0;iL--){
  235.             *paF++=*pbF++;
  236.             *paF++=*pbF++;
  237.             *paF++=*pbF++;
  238.             *paF++=*pbF++;
  239.             *paF++=*pbF++;
  240.             *paF++=*pbF++;
  241.             *paF++=*pbF++;
  242.             *paF++=*pbF++;
  243.             *paF++=*pbF++;
  244.             *paF++=*pbF++;
  245.         }
  246.         s=StopTimerSecs(timer)/n-overhead;
  247.         ffprintf(o,"%11.3f µs    *paF++=*pbF++;        // double, memory to memory, %.1f MB/s\n",s*1e6,sizeof(*paF)*1e-6/s);
  248.         n*=sizeof(*paF)/4;
  249.     }
  250.     {
  251.         register double *paF,*pbF;
  252.         unsigned long bytes=sizeof(*paF);
  253.  
  254.         n/=sizeof(*paF)/4;
  255.         paF=(void *)buffer;
  256.         pbF=(void *)buffer2;
  257.         paF--;pbF--;
  258.         StartTimer(timer);
  259.         for(iL=n/10;iL>0;iL--){
  260.             *++paF=*++pbF;
  261.             *++paF=*++pbF;
  262.             *++paF=*++pbF;
  263.             *++paF=*++pbF;
  264.             *++paF=*++pbF;
  265.             *++paF=*++pbF;
  266.             *++paF=*++pbF;
  267.             *++paF=*++pbF;
  268.             *++paF=*++pbF;
  269.             *++paF=*++pbF;
  270.         }
  271.         s=StopTimerSecs(timer)/n-overhead;
  272.         ffprintf(o,"%11.3f µs    *++paF=*++pbF;        // double, memory to memory, %.1f MB/s\n",s*1e6,sizeof(*paF)*1e-6/s);
  273.         n*=sizeof(*paF)/4;
  274.     }
  275.     {
  276.         register float *paF,*pbF;
  277.  
  278.         n/=sizeof(*paF)/4;
  279.         paF=(float *)buffer;
  280.         pbF=(float *)buffer2;
  281.         StartTimer(timer);
  282.         for(iL=n/10;iL>0;iL--){
  283.             *paF++=*pbF++;
  284.             *paF++=*pbF++;
  285.             *paF++=*pbF++;
  286.             *paF++=*pbF++;
  287.             *paF++=*pbF++;
  288.             *paF++=*pbF++;
  289.             *paF++=*pbF++;
  290.             *paF++=*pbF++;
  291.             *paF++=*pbF++;
  292.             *paF++=*pbF++;
  293.         }
  294.         s=StopTimerSecs(timer)/n-overhead;
  295.         ffprintf(o,"%11.3f µs    *paF++=*pbF++;        // float, memory to memory, %.1f MB/s\n",s*1e6,sizeof(*paF)*1e-6/s);
  296.         n*=sizeof(*paF)/4;
  297.     }
  298.     {
  299.         register float *paF,*pbF;
  300.  
  301.         n/=sizeof(*paF)/4;
  302.         paF=(void *)buffer;
  303.         pbF=(void *)buffer2;
  304.         paF--;pbF--;
  305.         StartTimer(timer);
  306.         for(iL=n/10;iL>0;iL--){
  307.             *++paF=*++pbF;
  308.             *++paF=*++pbF;
  309.             *++paF=*++pbF;
  310.             *++paF=*++pbF;
  311.             *++paF=*++pbF;
  312.             *++paF=*++pbF;
  313.             *++paF=*++pbF;
  314.             *++paF=*++pbF;
  315.             *++paF=*++pbF;
  316.             *++paF=*++pbF;
  317.         }
  318.         s=StopTimerSecs(timer)/n-overhead;
  319.         ffprintf(o,"%11.3f µs    *++paF=*++pbF;        // float, memory to memory, %.1f MB/s\n",s*1e6,sizeof(*paF)*1e-6/s);
  320.         n*=sizeof(*paF)/4;
  321.     }
  322.     {
  323.         paL=(void *)buffer;
  324.         pbL=(void *)buffer2;
  325.         StartTimer(timer);
  326.         for(iL=n/10;iL>0;iL--){
  327.             *paL++=*pbL++;
  328.             *paL++=*pbL++;
  329.             *paL++=*pbL++;
  330.             *paL++=*pbL++;
  331.             *paL++=*pbL++;
  332.             *paL++=*pbL++;
  333.             *paL++=*pbL++;
  334.             *paL++=*pbL++;
  335.             *paL++=*pbL++;
  336.             *paL++=*pbL++;
  337.         }
  338.         s=StopTimerSecs(timer)/n-overhead;
  339.         ffprintf(o,"%11.3f µs    *paL++=*pbL++;        // long, memory to memory, %.1f MB/s\n",s*1e6,sizeof(*paL)*1e-6/s);
  340.     }
  341.  
  342.     Gestalt(gestaltQuickdrawVersion,&quickDraw);
  343.     if(quickDraw>=gestalt8BitQD){
  344.         device=GetMainDevice();
  345.         if(device!=NULL){
  346.             paL=(long *)(**(**device).gdPMap).baseAddr;
  347.             if(paL!=NULL){
  348.                 signed char mode=true32b;
  349.                 long *pSave=paL;
  350.                 
  351.                 StartTimer(timer);
  352.                 if(can32)SwapMMUMode((void *)&mode);
  353.                 for(iL=n/10;iL>0;iL--) paL-=10;
  354.                 if(can32)SwapMMUMode((void *)&mode);
  355.                 s0=StopTimerSecs(timer)/n-overhead;
  356.                 paL=pSave;
  357.                 pbL=(long *)buffer2;
  358.                 StartTimer(timer);
  359.                 if(can32)SwapMMUMode((void *)&mode);
  360.                 for(iL=n/10;iL>0;iL--){
  361.                     *paL++=*pbL++;
  362.                     *paL++=*pbL++;
  363.                     *paL++=*pbL++;
  364.                     *paL++=*pbL++;
  365.                     *paL++=*pbL++;
  366.                     *paL++=*pbL++;
  367.                     *paL++=*pbL++;
  368.                     *paL++=*pbL++;
  369.                     *paL++=*pbL++;
  370.                     *paL++=*pbL++;
  371.                     paL-=10;
  372.                 }
  373.                 if(can32)SwapMMUMode((void *)&mode);
  374.                 s=StopTimerSecs(timer)/n-overhead;
  375.                 s-=s0;                                    // remove time for the paL-=10;
  376.                 ffprintf(o,"%11.3f µs    *paL++=*pbL++;        // long, memory to video mem. %.1f MB/s\n",s*1e6,4e-6/s);
  377.  
  378.                 {
  379.                     Boolean tryIt=1;
  380.                     char *blockMoveName;
  381.  
  382.                     //if(pci)tryIt=Choose(tryIt,"\nTry using BlockMoveDataUncached to copy from memory to video buffer?\n",noYes,2);
  383.                     //else tryIt=Choose(tryIt,"\nTry using BlockMoveData to copy from memory to video buffer?\n",noYes,2);
  384.                     if(tryIt){
  385.                         // this fails on some Macs
  386.                         Boolean hasBlockMoveDataUncached;
  387.                 
  388.                         #if GENERATINGCFM && GENERATINGPOWERPC
  389.                             hasBlockMoveDataUncached= (Ptr)BlockMoveDataUncached != (Ptr)kUnresolvedCFragSymbolAddress;
  390.                         #else
  391.                             hasBlockMoveDataUncached=0;
  392.                         #endif
  393.                         if(hasBlockMoveDataUncached)blockMoveName="BlockMoveDataUncached";
  394.                         else blockMoveName="BlockMoveData";
  395.                         paL=pSave;
  396.                         pbL=(long *)buffer2;
  397.                         BlockMoveData(paL,pbL,4*n);    // first copy from screen to memory, so we won't mess up screen
  398.                         StartTimer(timer);
  399.                         if(hasBlockMoveDataUncached){
  400.                             #if GENERATINGCFM && GENERATINGPOWERPC
  401.                                 BlockMoveDataUncached(pbL,paL,4*n);
  402.                             #endif
  403.                         }else BlockMoveData(pbL,paL,4*n);
  404.                         s=StopTimerSecs(timer)-overhead;
  405.                         ffprintf(o,"%11.3f ms    %s(,,%ld);    // mem.to vid.mem. %.1f MB/s\n"
  406.                             ,s*1e3,blockMoveName,n*4,n*4/1024./1024./s);
  407.                     }
  408.                     if(tryIt && pci){
  409.                         // this fails on some Macs
  410.                         Boolean hasBlockCopy;
  411.                 
  412.                         #if GENERATINGCFM && GENERATINGPOWERPC
  413.                             hasBlockCopy= (Ptr)BlockCopy != (Ptr)kUnresolvedCFragSymbolAddress;
  414.                         #else
  415.                             hasBlockCopy=0;
  416.                         #endif
  417.                         if(hasBlockCopy)blockMoveName="BlockCopy";
  418.                         else blockMoveName="BlockMoveData";
  419.                         paL=pSave;
  420.                         pbL=(long *)buffer2;
  421.                         BlockMoveData(paL,pbL,4*n);    // first copy from screen to memory, so we won't mess up screen
  422.                         StartTimer(timer);
  423.                         if(hasBlockCopy){
  424.                             #if GENERATINGCFM && GENERATINGPOWERPC
  425.                                 BlockCopy(pbL,paL,4*n);
  426.                             #endif
  427.                         }else BlockMoveData(pbL,paL,4*n);
  428.                         s=StopTimerSecs(timer)-overhead;
  429.                         ffprintf(o,"%11.3f ms    %s(,,%ld);    // mem.to vid.mem. %.1f MB/s\n"
  430.                             ,s*1e3,blockMoveName,n*4,n*4/1024./1024./s);
  431.                     }
  432.                 }
  433.             }
  434.         }
  435.     }
  436.     DisposeHandle(bufferHandle);
  437.     buffer=buffer2=NULL;
  438.  
  439. // Time the VideoToolbox routines that copy images (based on CopyBits and CopyBitsQuickly).
  440.     Gestalt(gestaltQuickdrawVersion,&quickDraw);
  441.     if(quickDraw>=gestalt8BitQD){
  442.         unsigned long row[256],row2[256];
  443.         int rowLength=256,clutSize;
  444.         
  445.         assert(StackSpace()>4000);
  446.         n/=100;
  447.         device=GetMainDevice();
  448.         clutSize=GDClutSize(device);
  449.         for(i=0;i<rowLength;i++)row[i]=nrand(clutSize);
  450.         StartTimer(timer);
  451.         for(iL=n;iL>0;iL--){
  452.             SetDevicePixelsQuickly(device,0,0,row,rowLength);
  453.         }
  454.         // NOTE: if you single step through this in the Debugger
  455.         // you'll get an apparent read-back error if the Debugger
  456.         // redraws the Menu bar between writing and reading the pixels.
  457.         s=StopTimerSecs(timer)/n-overhead;
  458.         GetDevicePixelsQuickly(device,0,0,row2,rowLength);
  459.         ffprintf(o,"%11.3f ms    SetPixelsQuickly(,,,,%d);// %d-bit pixels, %.3f MB/s\n",s*1e3
  460.             ,(int)rowLength,(int)(**(**device).gdPMap).pixelSize
  461.             ,(double)rowLength*(**(**device).gdPMap).pixelSize/8/1024/1024/s);
  462.  
  463.         StartTimer(timer);
  464.         for(iL=n;iL>0;iL--){
  465.             GetDevicePixelsQuickly(device,0,0,row,rowLength);
  466.         }
  467.         s=StopTimerSecs(timer)/n-overhead;
  468.         ffprintf(o,"%11.3f ms    GetPixelsQuickly(,,,,%d);// %d-bit pixels, %.3f MB/s\n",s*1e3
  469.             ,(int)rowLength,(int)(**(**device).gdPMap).pixelSize
  470.             ,(double)rowLength*(**(**device).gdPMap).pixelSize/8/1024/1024/s);
  471.         n*=100;
  472.  
  473.         for(i=0;i<1;i++)if(row2[i]!=row[i])printf("Pixel %d: wrote %ld != read %ld\n"
  474.             ,(int)i,row[i],row2[i]);
  475.  
  476.     }
  477.  
  478.     if(quickDraw>=gestalt32BitQD){
  479.         GWorldPtr aWorld,bWorld;
  480.         Rect r;
  481.         int error,pixelSize;
  482.         double pixels;
  483.  
  484.         n=2;
  485.         SetRect(&r,0,0,100,100);
  486.         pixels=(double)(r.right-r.left)*(r.bottom-r.top);
  487.         error=NewGWorld(&aWorld,8,&r,NULL,NULL,0);
  488.         if(!error)error=NewGWorld(&bWorld,8,&r,NULL,NULL,0);
  489.         if(!error){
  490.             LockPixels(GetGWorldPixMap(aWorld));
  491.             LockPixels(GetGWorldPixMap(bWorld));
  492.             StartTimer(timer);
  493.             for(iL=n;iL>0;iL--){
  494.                 CopyWindows(aWorld,bWorld,&aWorld->portRect,&aWorld->portRect,srcCopy,NULL);
  495.             }
  496.             s=StopTimerSecs(timer)/n-overhead;
  497.             pixelSize=(**GetGWorldPixMap(aWorld)).pixelSize;
  498.             ffprintf(o,"%11.3f ms    CopyWindows(,,,,srcCopy,);// %dx%dx%d, %.3f MB/s\n"
  499.                 ,s*1e3,(int)r.right,(int)r.bottom
  500.                 ,pixelSize,pixels*pixelSize/8/1024/1024/s);
  501.         }
  502.         DisposeGWorld(aWorld);
  503.         DisposeGWorld(bWorld);
  504.         SetRect(&r,0,0,100,100);
  505.         pixels=(double)(r.right-r.left)*(r.bottom-r.top);
  506.         error=NewGWorld(&bWorld,8,&r,NULL,NULL,0);
  507.         ShrinkRect(&r,20,1);
  508.         if(!error)error=NewGWorld(&aWorld,8,&r,NULL,NULL,0);
  509.         if(!error){
  510.             LockPixels(GetGWorldPixMap(aWorld));
  511.             LockPixels(GetGWorldPixMap(bWorld));
  512.             StartTimer(timer);
  513.             for(iL=n;iL>0;iL--){
  514.                 CopyWindows(aWorld,bWorld,&aWorld->portRect,&bWorld->portRect,srcCopy,NULL);
  515.             }
  516.             s=StopTimerSecs(timer)/n-overhead;
  517.             pixelSize=(**GetGWorldPixMap(aWorld)).pixelSize;
  518.             ffprintf(o,"%11.3f ms    CopyWindows(,,,,srcCopy,);// %dx%d to %dx%dx%d, %.3f MB/s\n"
  519.                 ,s*1e3
  520.                 ,(int)aWorld->portRect.right,(int)aWorld->portRect.bottom
  521.                 ,(int)bWorld->portRect.right,(int)bWorld->portRect.bottom
  522.                 ,pixelSize,pixels*pixelSize/8/1024/1024/s);
  523.         }
  524.         DisposeGWorld(aWorld);
  525.         DisposeGWorld(bWorld);
  526.         SetRect(&r,0,0,100,100);
  527.         pixels=(double)(r.right-r.left)*(r.bottom-r.top);
  528.         error=NewGWorld(&bWorld,8,&r,NULL,NULL,0);
  529.         ShrinkRect(&r,1,20);
  530.         if(!error)error=NewGWorld(&aWorld,8,&r,NULL,NULL,0);
  531.         if(!error){
  532.             LockPixels(GetGWorldPixMap(aWorld));
  533.             LockPixels(GetGWorldPixMap(bWorld));
  534.             StartTimer(timer);
  535.             for(iL=n;iL>0;iL--){
  536.                 CopyWindows(aWorld,bWorld,&aWorld->portRect,&bWorld->portRect,srcCopy,NULL);
  537.             }
  538.             s=StopTimerSecs(timer)/n-overhead;
  539.             pixelSize=(**GetGWorldPixMap(aWorld)).pixelSize;
  540.             r=aWorld->portRect;
  541.             ffprintf(o,"%11.3f ms    CopyWindows(,,,,srcCopy,);// %dx%d to %dx%dx%d, %.3f MB/s\n"
  542.                 ,s*1e3
  543.                 ,(int)aWorld->portRect.right,(int)aWorld->portRect.bottom
  544.                 ,(int)bWorld->portRect.right,(int)bWorld->portRect.bottom
  545.                 ,pixelSize,pixels*pixelSize/8/1024/1024/s);
  546.         }
  547.         DisposeGWorld(aWorld);
  548.         DisposeGWorld(bWorld);
  549.         n=100000;
  550.     }
  551.     if(quickDraw>=gestalt32BitQD){
  552.         GWorldPtr aWorld,bWorld;
  553.         Rect r;
  554.         int error,pixelSize;
  555.         double pixels;
  556.  
  557.         n=2;
  558.         SetRect(&r,0,0,100,100);
  559.         pixels=(double)(r.right-r.left)*(r.bottom-r.top);
  560.         error=NewGWorld(&aWorld,8,&r,NULL,NULL,0);
  561.         if(!error)error=NewGWorld(&bWorld,8,&r,NULL,NULL,0);
  562.         if(!error){
  563.             LockPixels(GetGWorldPixMap(aWorld));
  564.             LockPixels(GetGWorldPixMap(bWorld));
  565.             StartTimer(timer);
  566.             for(iL=n;iL>0;iL--){
  567.                 CopyWindows(aWorld,bWorld,&aWorld->portRect,&aWorld->portRect,srcCopyLiterally,NULL);
  568.             }
  569.             s=StopTimerSecs(timer)/n-overhead;
  570.             pixelSize=(**GetGWorldPixMap(aWorld)).pixelSize;
  571.             ffprintf(o,"%11.3f ms    CopyWindows(,,,,srcCopyLiterally,);// %dx%dx%d, %.3f MB/s\n"
  572.                 ,s*1e3,(int)r.right,(int)r.bottom
  573.                 ,pixelSize,pixels*pixelSize/8/1024/1024/s);
  574.         }
  575.         DisposeGWorld(aWorld);
  576.         DisposeGWorld(bWorld);
  577.         SetRect(&r,0,0,100,100);
  578.         pixels=(double)(r.right-r.left)*(r.bottom-r.top);
  579.         error=NewGWorld(&bWorld,8,&r,NULL,NULL,0);
  580.         ShrinkRect(&r,20,1);
  581.         if(!error)error=NewGWorld(&aWorld,8,&r,NULL,NULL,0);
  582.         if(!error){
  583.             LockPixels(GetGWorldPixMap(aWorld));
  584.             LockPixels(GetGWorldPixMap(bWorld));
  585.             StartTimer(timer);
  586.             for(iL=n;iL>0;iL--){
  587.                 CopyWindows(aWorld,bWorld,&aWorld->portRect,&bWorld->portRect,srcCopyLiterally,NULL);
  588.             }
  589.             s=StopTimerSecs(timer)/n-overhead;
  590.             pixelSize=(**GetGWorldPixMap(aWorld)).pixelSize;
  591.             ffprintf(o,"%11.3f ms    CopyWindows(,,,,srcCopyLiterally,);// %dx%d to %dx%dx%d, %.3f MB/s\n"
  592.                 ,s*1e3
  593.                 ,(int)aWorld->portRect.right,(int)aWorld->portRect.bottom
  594.                 ,(int)bWorld->portRect.right,(int)bWorld->portRect.bottom
  595.                 ,pixelSize,pixels*pixelSize/8/1024/1024/s);
  596.         }
  597.         DisposeGWorld(aWorld);
  598.         DisposeGWorld(bWorld);
  599.         SetRect(&r,0,0,100,100);
  600.         pixels=(double)(r.right-r.left)*(r.bottom-r.top);
  601.         error=NewGWorld(&bWorld,8,&r,NULL,NULL,0);
  602.         ShrinkRect(&r,1,20);
  603.         if(!error)error=NewGWorld(&aWorld,8,&r,NULL,NULL,0);
  604.         if(!error){
  605.             LockPixels(GetGWorldPixMap(aWorld));
  606.             LockPixels(GetGWorldPixMap(bWorld));
  607.             StartTimer(timer);
  608.             for(iL=n;iL>0;iL--){
  609.                 CopyWindows(aWorld,bWorld,&aWorld->portRect,&bWorld->portRect,srcCopyLiterally,NULL);
  610.             }
  611.             s=StopTimerSecs(timer)/n-overhead;
  612.             pixelSize=(**GetGWorldPixMap(aWorld)).pixelSize;
  613.             r=aWorld->portRect;
  614.             ffprintf(o,"%11.3f ms    CopyWindows(,,,,srcCopyLiterally,);// %dx%d to %dx%dx%d, %.3f MB/s\n"
  615.                 ,s*1e3
  616.                 ,(int)aWorld->portRect.right,(int)aWorld->portRect.bottom
  617.                 ,(int)bWorld->portRect.right,(int)bWorld->portRect.bottom
  618.                 ,pixelSize,pixels*pixelSize/8/1024/1024/s);
  619.         }
  620.         DisposeGWorld(aWorld);
  621.         DisposeGWorld(bWorld);
  622.         n=100000;
  623.     }
  624.  
  625.     if(1){            // time long arithmetic
  626.         StartTimer(timer);
  627.         for(iL=n/10;iL>0;iL--){
  628.             jL=kL;
  629.             jL=kL;
  630.             jL=kL;
  631.             jL=kL;
  632.             jL=kL;
  633.             jL=kL;
  634.             jL=kL;
  635.             jL=kL;
  636.             jL=kL;
  637.             jL=kL;
  638.         }
  639.         s=StopTimerSecs(timer)/n-overhead;
  640.         ffprintf(o,"%11.3f µs    jL=kL;            // long, register to register\n",s*1e6);
  641.     
  642.         StartTimer(timer);
  643.         for(iL=n/10;iL>0;iL--){
  644.             jL=kL>>1;
  645.             jL=kL>>1;
  646.             jL=kL>>1;
  647.             jL=kL>>1;
  648.             jL=kL>>1;
  649.             jL=kL>>1;
  650.             jL=kL>>1;
  651.             jL=kL>>1;
  652.             jL=kL>>1;
  653.             jL=kL>>1;
  654.         }
  655.         s=StopTimerSecs(timer)/n-overhead;
  656.         ffprintf(o,"%11.3f µs    jL=kL>>1;\n",s*1e6);
  657.     
  658.         StartTimer(timer);
  659.         for(iL=n/10;iL>0;iL--){
  660.             jL=kL+mL;
  661.             jL=kL+mL;
  662.             jL=kL+mL;
  663.             jL=kL+mL;
  664.             jL=kL+mL;
  665.             jL=kL+mL;
  666.             jL=kL+mL;
  667.             jL=kL+mL;
  668.             jL=kL+mL;
  669.             jL=kL+mL;
  670.         }
  671.         s=StopTimerSecs(timer)/n-overhead;
  672.         ffprintf(o,"%11.3f µs    jL=kL+mL;\n",s*1e6);
  673.     
  674.         StartTimer(timer);
  675.         for(iL=n/10;iL>0;iL--){
  676.             jL=kL-mL;
  677.             jL=kL-mL;
  678.             jL=kL-mL;
  679.             jL=kL-mL;
  680.             jL=kL-mL;
  681.             jL=kL-mL;
  682.             jL=kL-mL;
  683.             jL=kL-mL;
  684.             jL=kL-mL;
  685.             jL=kL-mL;
  686.         }
  687.         s=StopTimerSecs(timer)/n-overhead;
  688.         ffprintf(o,"%11.3f µs    jL=kL-mL;\n",s*1e6);
  689.     
  690.         n/=10;            /* all other operations take at least several microseconds */
  691.         StartTimer(timer);
  692.         for(iL=n/10;iL>0;iL--){
  693.             jL=kL*mL;
  694.             jL=kL*mL;
  695.             jL=kL*mL;
  696.             jL=kL*mL;
  697.             jL=kL*mL;
  698.             jL=kL*mL;
  699.             jL=kL*mL;
  700.             jL=kL*mL;
  701.             jL=kL*mL;
  702.             jL=kL*mL;
  703.         }
  704.         s=StopTimerSecs(timer)/n-overhead;
  705.         ffprintf(o,"%11.3f µs    jL=kL*mL;\n",s*1e6);
  706.     
  707.         StartTimer(timer);
  708.         for(iL=n/10;iL>0;iL--){
  709.             jL=kL/mL;
  710.             jL=kL/mL;
  711.             jL=kL/mL;
  712.             jL=kL/mL;
  713.             jL=kL/mL;
  714.             jL=kL/mL;
  715.             jL=kL/mL;
  716.             jL=kL/mL;
  717.             jL=kL/mL;
  718.             jL=kL/mL;
  719.         }
  720.         s=StopTimerSecs(timer)/n-overhead;
  721.         ffprintf(o,"%11.3f µs    jL=kL/mL;\n",s*1e6);
  722.         n*=10;
  723.     }
  724.     if(1){                // time short arithmetic
  725.         register short jH,kH=1234,mH=5678;
  726.         
  727.         StartTimer(timer);
  728.         for(iL=n/10;iL>0;iL--){
  729.             jH=kH;
  730.             jH=kH;
  731.             jH=kH;
  732.             jH=kH;
  733.             jH=kH;
  734.             jH=kH;
  735.             jH=kH;
  736.             jH=kH;
  737.             jH=kH;
  738.             jH=kH;
  739.         }
  740.         s=StopTimerSecs(timer)/n-overhead;
  741.         ffprintf(o,"%11.3f µs    jH=kH;            // short, register to register\n",s*1e6);
  742.     
  743.         StartTimer(timer);
  744.         for(iL=n/10;iL>0;iL--){
  745.             jH=kH>>1;
  746.             jH=kH>>1;
  747.             jH=kH>>1;
  748.             jH=kH>>1;
  749.             jH=kH>>1;
  750.             jH=kH>>1;
  751.             jH=kH>>1;
  752.             jH=kH>>1;
  753.             jH=kH>>1;
  754.             jH=kH>>1;
  755.         }
  756.         s=StopTimerSecs(timer)/n-overhead;
  757.         ffprintf(o,"%11.3f µs    jH=kH>>1;\n",s*1e6);
  758.     
  759.         StartTimer(timer);
  760.         for(iL=n/10;iL>0;iL--){
  761.             jH=kH+mH;
  762.             jH=kH+mH;
  763.             jH=kH+mH;
  764.             jH=kH+mH;
  765.             jH=kH+mH;
  766.             jH=kH+mH;
  767.             jH=kH+mH;
  768.             jH=kH+mH;
  769.             jH=kH+mH;
  770.             jH=kH+mH;
  771.         }
  772.         s=StopTimerSecs(timer)/n-overhead;
  773.         ffprintf(o,"%11.3f µs    jH=kH+mH;\n",s*1e6);
  774.     
  775.         StartTimer(timer);
  776.         for(iL=n/10;iL>0;iL--){
  777.             jH=kH-mH;
  778.             jH=kH-mH;
  779.             jH=kH-mH;
  780.             jH=kH-mH;
  781.             jH=kH-mH;
  782.             jH=kH-mH;
  783.             jH=kH-mH;
  784.             jH=kH-mH;
  785.             jH=kH-mH;
  786.             jH=kH-mH;
  787.         }
  788.         s=StopTimerSecs(timer)/n-overhead;
  789.         ffprintf(o,"%11.3f µs    jH=kH-mH;\n",s*1e6);
  790.     
  791.         n/=10;            /* all other operations take at least several microseconds */
  792.         StartTimer(timer);
  793.         for(iL=n/10;iL>0;iL--){
  794.             jH=kH*mH;
  795.             jH=kH*mH;
  796.             jH=kH*mH;
  797.             jH=kH*mH;
  798.             jH=kH*mH;
  799.             jH=kH*mH;
  800.             jH=kH*mH;
  801.             jH=kH*mH;
  802.             jH=kH*mH;
  803.             jH=kH*mH;
  804.         }
  805.         s=StopTimerSecs(timer)/n-overhead;
  806.         ffprintf(o,"%11.3f µs    jH=kH*mH;\n",s*1e6);
  807.     
  808.         StartTimer(timer);
  809.         for(iL=n/10;iL>0;iL--){
  810.             jH=kH/mH;
  811.             jH=kH/mH;
  812.             jH=kH/mH;
  813.             jH=kH/mH;
  814.             jH=kH/mH;
  815.             jH=kH/mH;
  816.             jH=kH/mH;
  817.             jH=kH/mH;
  818.             jH=kH/mH;
  819.             jH=kH/mH;
  820.         }
  821.         s=StopTimerSecs(timer)/n-overhead;
  822.         ffprintf(o,"%11.3f µs    jH=kH/mH;\n",s*1e6);
  823.         n*=10;
  824.     }
  825.  
  826.     n/=10;            /* all other operations take at least several microseconds */
  827.  
  828.     if(1){        // time double arithmetic
  829.         StartTimer(timer);
  830.         for(iL=n/10;iL>0;iL--){
  831.             x=y;
  832.             x=y;
  833.             x=y;
  834.             x=y;
  835.             x=y;
  836.             x=y;
  837.             x=y;
  838.             x=y;
  839.             x=y;
  840.             x=y;
  841.         }
  842.         s=StopTimerSecs(timer)/n-overhead;
  843.         ffprintf(o,"%11.3f µs    x=y;            // double\n",s*1e6);
  844.     
  845.         StartTimer(timer);
  846.         for(iL=n/10;iL>0;iL--){
  847.             x=y+z;
  848.             x=y+z;
  849.             x=y+z;
  850.             x=y+z;
  851.             x=y+z;
  852.             x=y+z;
  853.             x=y+z;
  854.             x=y+z;
  855.             x=y+z;
  856.             x=y+z;
  857.         }
  858.         s=StopTimerSecs(timer)/n-overhead;
  859.         ffprintf(o,"%11.3f µs    x=y+z;\n",s*1e6);
  860.     
  861.         StartTimer(timer);
  862.         for(iL=n/10;iL>0;iL--){
  863.             x=y-z;
  864.             x=y-z;
  865.             x=y-z;
  866.             x=y-z;
  867.             x=y-z;
  868.             x=y-z;
  869.             x=y-z;
  870.             x=y-z;
  871.             x=y-z;
  872.             x=y-z;
  873.         }
  874.         s=StopTimerSecs(timer)/n-overhead;
  875.         ffprintf(o,"%11.3f µs    x=y-z;\n",s*1e6);
  876.     
  877.         StartTimer(timer);
  878.         for(iL=n/10;iL>0;iL--){
  879.             x=y*z;
  880.             x=y*z;
  881.             x=y*z;
  882.             x=y*z;
  883.             x=y*z;
  884.             x=y*z;
  885.             x=y*z;
  886.             x=y*z;
  887.             x=y*z;
  888.             x=y*z;
  889.         }
  890.         s=StopTimerSecs(timer)/n-overhead;
  891.         ffprintf(o,"%11.3f µs    x=y*z;\n",s*1e6);
  892.     
  893.         StartTimer(timer);
  894.         for(iL=n/10;iL>0;iL--){
  895.             x=y/z;
  896.             x=y/z;
  897.             x=y/z;
  898.             x=y/z;
  899.             x=y/z;
  900.             x=y/z;
  901.             x=y/z;
  902.             x=y/z;
  903.             x=y/z;
  904.             x=y/z;
  905.         }
  906.         s=StopTimerSecs(timer)/n-overhead;
  907.         ffprintf(o,"%11.3f µs    x=y/z;\n",s*1e6);
  908.     }
  909.     
  910.     if(1){                // time transcendental functions
  911.         StartTimer(timer);
  912.         for(iL=n/10;iL>0;iL--){
  913.             x=sin(y);
  914.             x=sin(y);
  915.             x=sin(y);
  916.             x=sin(y);
  917.             x=sin(y);
  918.             x=sin(y);
  919.             x=sin(y);
  920.             x=sin(y);
  921.             x=sin(y);
  922.             x=sin(y);
  923.         }
  924.         s=StopTimerSecs(timer)/n-overhead;
  925.         ffprintf(o,"%11.3f µs    x=sin(y);\n",s*1e6);
  926.     
  927.         StartTimer(timer);
  928.         for(iL=n/10;iL>0;iL--){
  929.             x=sqrt(y);
  930.             x=sqrt(y);
  931.             x=sqrt(y);
  932.             x=sqrt(y);
  933.             x=sqrt(y);
  934.             x=sqrt(y);
  935.             x=sqrt(y);
  936.             x=sqrt(y);
  937.             x=sqrt(y);
  938.             x=sqrt(y);
  939.         }
  940.         s=StopTimerSecs(timer)/n-overhead;
  941.         ffprintf(o,"%11.3f µs    x=sqrt(y);\n",s*1e6);
  942.     
  943.         n/=100;
  944.         StartTimer(timer);
  945.         for(iL=n/10;iL>0;iL--){
  946.             x=log(y);
  947.             x=log(y);
  948.             x=log(y);
  949.             x=log(y);
  950.             x=log(y);
  951.             x=log(y);
  952.             x=log(y);
  953.             x=log(y);
  954.             x=log(y);
  955.             x=log(y);
  956.         }
  957.         s=StopTimerSecs(timer)/n-overhead;
  958.         ffprintf(o,"%11.3f µs    x=log(y);\n",s*1e6);
  959.         StartTimer(timer);
  960.         for(iL=n/10;iL>0;iL--){
  961.             x=exp(y);
  962.             x=exp(y);
  963.             x=exp(y);
  964.             x=exp(y);
  965.             x=exp(y);
  966.             x=exp(y);
  967.             x=exp(y);
  968.             x=exp(y);
  969.             x=exp(y);
  970.             x=exp(y);
  971.         }
  972.         s=StopTimerSecs(timer)/n-overhead;
  973.         ffprintf(o,"%11.3f µs    x=exp(y);\n",s*1e6);
  974.         n*=100;
  975.     
  976.     }
  977.  
  978.     o[1]=NULL;        /* that's all we want to save in “TimeCPU results” */
  979.  
  980.     if(1){                    // time Fixed
  981.         yF=zF=0x12341234;
  982.         StartTimer(timer);
  983.         for(iL=n/10;iL>0;iL--){
  984.             xF=FixMul(yF,zF);
  985.             xF=FixMul(yF,zF);
  986.             xF=FixMul(yF,zF);
  987.             xF=FixMul(yF,zF);
  988.             xF=FixMul(yF,zF);
  989.             xF=FixMul(yF,zF);
  990.             xF=FixMul(yF,zF);
  991.             xF=FixMul(yF,zF);
  992.             xF=FixMul(yF,zF);
  993.             xF=FixMul(yF,zF);
  994.         }
  995.         s=StopTimerSecs(timer)/n-overhead;
  996.         ffprintf(o,"%11.3f µs    xF=FixMul(yF,zF);    // Fixed\n",s*1e6);
  997.     
  998.         yF=(long)(PI*256);
  999.         zF=(long)(1.1*256);
  1000.         StartTimer(timer);
  1001.         for(iL=n/10;iL>0;iL--){
  1002.             xF=FixDiv(yF,zF);
  1003.             xF=FixDiv(yF,zF);
  1004.             xF=FixDiv(yF,zF);
  1005.             xF=FixDiv(yF,zF);
  1006.             xF=FixDiv(yF,zF);
  1007.             xF=FixDiv(yF,zF);
  1008.             xF=FixDiv(yF,zF);
  1009.             xF=FixDiv(yF,zF);
  1010.             xF=FixDiv(yF,zF);
  1011.             xF=FixDiv(yF,zF);
  1012.         }
  1013.         s=StopTimerSecs(timer)/n-overhead;
  1014.         ffprintf(o,"%11.3f µs    xF=FixDiv(yF,zF);\n",s*1e6);
  1015.     
  1016.         StartTimer(timer);
  1017.         for(iL=n/10;iL>0;iL--){
  1018.             xF=FixRatio(123,1234);
  1019.             xF=FixRatio(123,1234);
  1020.             xF=FixRatio(123,1234);
  1021.             xF=FixRatio(123,1234);
  1022.             xF=FixRatio(123,1234);
  1023.             xF=FixRatio(123,1234);
  1024.             xF=FixRatio(123,1234);
  1025.             xF=FixRatio(123,1234);
  1026.             xF=FixRatio(123,1234);
  1027.             xF=FixRatio(123,1234);
  1028.         }
  1029.         s=StopTimerSecs(timer)/n-overhead;
  1030.         ffprintf(o,"%11.3f µs    xF=FixRatio(123,1234);\n",s*1e6);
  1031.     
  1032.         StartTimer(timer);
  1033.         for(iL=n/10;iL>0;iL--){
  1034.             xF=DoubleToFix(y);
  1035.             xF=DoubleToFix(y);
  1036.             xF=DoubleToFix(y);
  1037.             xF=DoubleToFix(y);
  1038.             xF=DoubleToFix(y);
  1039.             xF=DoubleToFix(y);
  1040.             xF=DoubleToFix(y);
  1041.             xF=DoubleToFix(y);
  1042.             xF=DoubleToFix(y);
  1043.             xF=DoubleToFix(y);
  1044.         }
  1045.         s=StopTimerSecs(timer)/n-overhead;
  1046.         ffprintf(o,"%11.3f µs    xF=DoubleToFix(y);\n",s*1e6);
  1047.     
  1048.         xF=(long)(PI*256);
  1049.         StartTimer(timer);
  1050.         for(iL=n/10;iL>0;iL--){
  1051.             x=FixToDouble(xF);
  1052.             x=FixToDouble(xF);
  1053.             x=FixToDouble(xF);
  1054.             x=FixToDouble(xF);
  1055.             x=FixToDouble(xF);
  1056.             x=FixToDouble(xF);
  1057.             x=FixToDouble(xF);
  1058.             x=FixToDouble(xF);
  1059.             x=FixToDouble(xF);
  1060.             x=FixToDouble(xF);
  1061.             x=FixToDouble(xF);
  1062.         }
  1063.         s=StopTimerSecs(timer)/n-overhead;
  1064.         ffprintf(o,"%11.3f µs    x=FixToDouble(xF);\n",s*1e6);
  1065.     }
  1066.     
  1067.     if(1){                // time rand()
  1068.         n*=10;
  1069.         for(;n>0;){
  1070.             bufferHandle=NewHandle(n);
  1071.             if(bufferHandle==NULL)bufferHandle=TempNewHandle(n,&osErr);
  1072.             if(bufferHandle!=NULL)break;
  1073.             n/=2;
  1074.             printf("Reducing iterations to %ld to fit in available memory.\n",n);
  1075.         }
  1076.         assert(bufferHandle!=NULL);
  1077.         HLockHi(bufferHandle);
  1078.         buffer=*bufferHandle;
  1079.         StartTimer(timer);
  1080.         s=StopTimerSecs(timer);
  1081.         StartTimer(timer);
  1082.         RandFill(buffer,n);
  1083.         s=StopTimerSecs(timer) - s;
  1084.         DisposeHandle(bufferHandle);
  1085.         buffer=NULL;
  1086.         ffprintf(o,"%11.3f µs    RandFill(,%ld);    // i.e. %4.1f µs/byte\n"
  1087.             ,s*1e6,n,s*1e6/n);
  1088.         n/=10;
  1089.     
  1090.         StartTimer(timer);
  1091.         for(iL=n/10;iL>0;iL--){
  1092.             i=randU();
  1093.             i=randU();
  1094.             i=randU();
  1095.             i=randU();
  1096.             i=randU();
  1097.             i=randU();
  1098.             i=randU();
  1099.             i=randU();
  1100.             i=randU();
  1101.             i=randU();
  1102.         }
  1103.         s=StopTimerSecs(timer)/n-overhead;
  1104.         ffprintf(o,"%11.3f µs    i=randU();        // i.e. %4.1f µs/byte\n",s*1e6, s*1e6/2.);
  1105.     
  1106.         StartTimer(timer);
  1107.         for(iL=n/10;iL>0;iL--){
  1108.             i=rand();
  1109.             i=rand();
  1110.             i=rand();
  1111.             i=rand();
  1112.             i=rand();
  1113.             i=rand();
  1114.             i=rand();
  1115.             i=rand();
  1116.             i=rand();
  1117.             i=rand();
  1118.         }
  1119.         s=StopTimerSecs(timer)/n-overhead;
  1120.         ffprintf(o,"%11.3f µs    i=rand();         // i.e. %4.1f µs/byte\n",s*1e6, s*1e6/1.);
  1121.     
  1122.         StartTimer(timer);
  1123.         for(iL=n/10;iL>0;iL--){
  1124.             i=Random();
  1125.             i=Random();
  1126.             i=Random();
  1127.             i=Random();
  1128.             i=Random();
  1129.             i=Random();
  1130.             i=Random();
  1131.             i=Random();
  1132.             i=Random();
  1133.             i=Random();
  1134.         }
  1135.         s=StopTimerSecs(timer)/n-overhead;
  1136.         ffprintf(o,"%11.3f µs    i=Random();\n",s*1e6);
  1137.     
  1138.         StartTimer(timer);
  1139.         for(iL=n/10;iL>0;iL--){
  1140.             i=nrand(127);
  1141.             i=nrand(127);
  1142.             i=nrand(127);
  1143.             i=nrand(127);
  1144.             i=nrand(127);
  1145.             i=nrand(127);
  1146.             i=nrand(127);
  1147.             i=nrand(127);
  1148.             i=nrand(127);
  1149.             i=nrand(127);
  1150.         }
  1151.         s=StopTimerSecs(timer)/n-overhead;
  1152.         ffprintf(o,"%11.3f µs    i=nrand(127);\n",s*1e6);
  1153.     
  1154.         StartTimer(timer);
  1155.         for(iL=n/10;iL>0;iL--){
  1156.             i=127L*randU()>>16;
  1157.             i=127L*randU()>>16;
  1158.             i=127L*randU()>>16;
  1159.             i=127L*randU()>>16;
  1160.             i=127L*randU()>>16;
  1161.             i=127L*randU()>>16;
  1162.             i=127L*randU()>>16;
  1163.             i=127L*randU()>>16;
  1164.             i=127L*randU()>>16;
  1165.             i=127L*randU()>>16;
  1166.         }
  1167.         s=StopTimerSecs(timer)/n-overhead;
  1168.         ffprintf(o,"%11.3f µs    i=127L*randU()>>16;\n",s*1e6);
  1169.     
  1170.         StartTimer(timer);
  1171.         for(iL=n/10;iL>0;iL--){
  1172.             i=127L*rand()>>15;
  1173.             i=127L*rand()>>15;
  1174.             i=127L*rand()>>15;
  1175.             i=127L*rand()>>15;
  1176.             i=127L*rand()>>15;
  1177.             i=127L*rand()>>15;
  1178.             i=127L*rand()>>15;
  1179.             i=127L*rand()>>15;
  1180.             i=127L*rand()>>15;
  1181.             i=127L*rand()>>15;
  1182.         }
  1183.         s=StopTimerSecs(timer)/n-overhead;
  1184.         ffprintf(o,"%11.3f µs    i=127L*rand()>>15;\n",s*1e6);
  1185.     
  1186.         StartTimer(timer);
  1187.         for(iL=n/10;iL>0;iL--){
  1188.             i=randU()%(unsigned short)127;
  1189.             i=randU()%(unsigned short)127;
  1190.             i=randU()%(unsigned short)127;
  1191.             i=randU()%(unsigned short)127;
  1192.             i=randU()%(unsigned short)127;
  1193.             i=randU()%(unsigned short)127;
  1194.             i=randU()%(unsigned short)127;
  1195.             i=randU()%(unsigned short)127;
  1196.             i=randU()%(unsigned short)127;
  1197.             i=randU()%(unsigned short)127;
  1198.         }
  1199.         s=StopTimerSecs(timer)/n-overhead;
  1200.         ffprintf(o,"%11.3f µs    i=randU()%%(unsigned short)127;\n",s*1e6);
  1201.     
  1202.         StartTimer(timer);
  1203.         for(iL=n/10;iL>0;iL--){
  1204.             i=rand()%127;
  1205.             i=rand()%127;
  1206.             i=rand()%127;
  1207.             i=rand()%127;
  1208.             i=rand()%127;
  1209.             i=rand()%127;
  1210.             i=rand()%127;
  1211.             i=rand()%127;
  1212.             i=rand()%127;
  1213.             i=rand()%127;
  1214.         }
  1215.         s=StopTimerSecs(timer)/n-overhead;
  1216.         ffprintf(o,"%11.3f µs    i=rand()%%127;\n",s*1e6);
  1217.     }
  1218.     DisposeTimer(timer);
  1219.     fclose(dataFile);    /* close “TimeCPU results” */
  1220.     DrawMenuBar();
  1221. }
  1222.  
  1223.